#!/usr/bin/env node

// ================================================
// Builder.Alyr.Net 智能体生成文件 [Builder.Alyr.Net] [2025-07-28]
// (c) 2020-2025 ALYR.NET
// ================================================

const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const readline = require('readline');
const multiFrameworkAdapter = require('./multi-framework-adapter');

/**
 * Builder.Alyr.Net多语言多框架代码生成CLI工具
 * @class AlyrCodeGenerator
 * @description 提供交互式的多语言多框架代码生成功能
 */
class AlyrCodeGenerator {
  constructor() {
    this.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    
    this.config = {
      language: '',
      framework: '',
      type: '',
      moduleName: '',
      outputPath: './generated'
    };
  }

  /**
   * 启动CLI工具
   */
  async start() {
    console.log(chalk.green.bold('🚀 Builder.Alyr.Net多语言多框架代码生成器'));
    console.log(chalk.blue('版权所有 © 2020-2025 ALYR.NET\n'));
    
    try {
      await this.showMainMenu();
    } catch (error) {
      console.error(chalk.red('❌ 生成失败:'), error.message);
    } finally {
      this.rl.close();
    }
  }

  /**
   * 显示主菜单
   */
  async showMainMenu() {
    console.log(chalk.yellow('请选择操作:'));
    console.log('1. 生成单个组件/控制器');
    console.log('2. 生成完整模块');
    console.log('3. 生成项目脚手架');
    console.log('4. 查看支持的技术栈');
    console.log('5. 退出\n');

    const choice = await this.question('请输入选项 (1-5): ');
    
    switch (choice.trim()) {
      case '1':
        await this.generateSingleComponent();
        break;
      case '2':
        await this.generateCompleteModule();
        break;
      case '3':
        await this.generateProjectScaffold();
        break;
      case '4':
        this.showSupportedTechStack();
        await this.showMainMenu();
        break;
      case '5':
        console.log(chalk.green('👋 再见！'));
        break;
      default:
        console.log(chalk.red('❌ 无效选项，请重新选择\n'));
        await this.showMainMenu();
    }
  }

  /**
   * 生成单个组件/控制器
   */
  async generateSingleComponent() {
    console.log(chalk.blue('\n📝 生成单个组件/控制器\n'));
    
    // 选择语言
    await this.selectLanguage();
    
    // 选择框架
    await this.selectFramework();
    
    // 选择类型
    await this.selectComponentType();
    
    // 输入模块名
    await this.inputModuleName();
    
    // 选择输出路径
    await this.selectOutputPath();
    
    // 生成代码
    await this.generateCode();
  }

  /**
   * 生成完整模块
   */
  async generateCompleteModule() {
    console.log(chalk.blue('\n🏗️ 生成完整模块\n'));
    
    // 选择语言
    await this.selectLanguage();
    
    // 选择框架
    await this.selectFramework();
    
    // 输入模块名
    await this.inputModuleName();
    
    // 选择输出路径
    await this.selectOutputPath();
    
    // 生成完整模块
    await this.generateCompleteModuleFiles();
  }

  /**
   * 生成项目脚手架
   */
  async generateProjectScaffold() {
    console.log(chalk.blue('\n🏗️ 生成项目脚手架\n'));
    
    // 选择语言
    await this.selectLanguage();
    
    // 选择框架
    await this.selectFramework();
    
    // 输入项目名
    const projectName = await this.question('请输入项目名称: ');
    this.config.projectName = projectName.trim();
    
    // 选择输出路径
    await this.selectOutputPath();
    
    // 生成项目结构
    await this.generateProjectStructure();
  }

  /**
   * 选择编程语言
   */
  async selectLanguage() {
    const languages = multiFrameworkAdapter.getSupportedLanguages();
    
    console.log(chalk.yellow('支持的编程语言:'));
    languages.forEach((lang, index) => {
      console.log(`${index + 1}. ${lang}`);
    });
    
    const choice = await this.question('\n请选择编程语言 (输入数字): ');
    const index = parseInt(choice.trim()) - 1;
    
    if (index >= 0 && index < languages.length) {
      this.config.language = languages[index];
      console.log(chalk.green(`✅ 已选择: ${this.config.language}\n`));
    } else {
      console.log(chalk.red('❌ 无效选择，请重新选择\n'));
      await this.selectLanguage();
    }
  }

  /**
   * 选择框架
   */
  async selectFramework() {
    const frameworks = multiFrameworkAdapter.getSupportedFrameworks();
    const allFrameworks = [];
    
    console.log(chalk.yellow('支持的框架:'));
    
    let index = 1;
    Object.entries(frameworks).forEach(([category, frameworkList]) => {
      console.log(chalk.cyan(`\n${category.toUpperCase()}:`));
      frameworkList.forEach(framework => {
        console.log(`${index}. ${framework}`);
        allFrameworks.push(framework);
        index++;
      });
    });
    
    const choice = await this.question('\n请选择框架 (输入数字): ');
    const selectedIndex = parseInt(choice.trim()) - 1;
    
    if (selectedIndex >= 0 && selectedIndex < allFrameworks.length) {
      this.config.framework = allFrameworks[selectedIndex];
      console.log(chalk.green(`✅ 已选择: ${this.config.framework}\n`));
    } else {
      console.log(chalk.red('❌ 无效选择，请重新选择\n'));
      await this.selectFramework();
    }
  }

  /**
   * 选择组件类型
   */
  async selectComponentType() {
    const types = ['controller', 'service', 'component', 'entity', 'dto'];
    
    console.log(chalk.yellow('组件类型:'));
    types.forEach((type, index) => {
      console.log(`${index + 1}. ${type}`);
    });
    
    const choice = await this.question('\n请选择组件类型 (输入数字): ');
    const index = parseInt(choice.trim()) - 1;
    
    if (index >= 0 && index < types.length) {
      this.config.type = types[index];
      console.log(chalk.green(`✅ 已选择: ${this.config.type}\n`));
    } else {
      console.log(chalk.red('❌ 无效选择，请重新选择\n'));
      await this.selectComponentType();
    }
  }

  /**
   * 输入模块名称
   */
  async inputModuleName() {
    const moduleName = await this.question('请输入模块名称 (如: user, article): ');
    this.config.moduleName = moduleName.trim();
    
    if (!this.config.moduleName) {
      console.log(chalk.red('❌ 模块名称不能为空\n'));
      await this.inputModuleName();
    } else {
      console.log(chalk.green(`✅ 模块名称: ${this.config.moduleName}\n`));
    }
  }

  /**
   * 选择输出路径
   */
  async selectOutputPath() {
    const defaultPath = './generated';
    const customPath = await this.question(`请输入输出路径 (默认: ${defaultPath}): `);
    
    this.config.outputPath = customPath.trim() || defaultPath;
    console.log(chalk.green(`✅ 输出路径: ${this.config.outputPath}\n`));
  }

  /**
   * 生成代码
   */
  async generateCode() {
    console.log(chalk.blue('🔨 正在生成代码...\n'));
    
    try {
      // 检查语言和框架组合是否支持
      if (!multiFrameworkAdapter.isSupported(this.config.language, this.config.framework)) {
        throw new Error(`不支持的语言和框架组合: ${this.config.language} + ${this.config.framework}`);
      }
      
      // 生成代码
      const code = multiFrameworkAdapter.generateCode(this.config);
      
      // 确保输出目录存在
      if (!fs.existsSync(this.config.outputPath)) {
        fs.mkdirSync(this.config.outputPath, { recursive: true });
      }
      
      // 生成文件名
      const fileName = this.generateFileName();
      const filePath = path.join(this.config.outputPath, fileName);
      
      // 写入文件
      fs.writeFileSync(filePath, code, 'utf8');
      
      console.log(chalk.green('✅ 代码生成成功!'));
      console.log(chalk.blue(`📁 文件路径: ${filePath}`));
      console.log(chalk.yellow(`📊 文件大小: ${(code.length / 1024).toFixed(2)} KB\n`));
      
      // 显示代码预览
      await this.showCodePreview(code);
      
    } catch (error) {
      console.error(chalk.red('❌ 代码生成失败:'), error.message);
    }
  }

  /**
   * 生成完整模块文件
   */
  async generateCompleteModuleFiles() {
    console.log(chalk.blue('🔨 正在生成完整模块...\n'));
    
    const moduleTypes = ['controller', 'service', 'entity', 'dto'];
    const generatedFiles = [];
    
    try {
      // 确保输出目录存在
      const moduleDir = path.join(this.config.outputPath, this.config.moduleName);
      if (!fs.existsSync(moduleDir)) {
        fs.mkdirSync(moduleDir, { recursive: true });
      }
      
      // 生成各种类型的文件
      for (const type of moduleTypes) {
        try {
          const config = { ...this.config, type };
          const code = multiFrameworkAdapter.generateCode(config);
          
          const fileName = this.generateFileName(type);
          const filePath = path.join(moduleDir, fileName);
          
          fs.writeFileSync(filePath, code, 'utf8');
          generatedFiles.push(filePath);
          
          console.log(chalk.green(`✅ 已生成: ${fileName}`));
        } catch (error) {
          console.log(chalk.yellow(`⚠️ 跳过 ${type}: ${error.message}`));
        }
      }
      
      console.log(chalk.green(`\n🎉 完整模块生成成功! 共生成 ${generatedFiles.length} 个文件`));
      console.log(chalk.blue(`📁 模块目录: ${moduleDir}\n`));
      
      // 显示生成的文件列表
      generatedFiles.forEach(file => {
        console.log(chalk.cyan(`  📄 ${path.basename(file)}`));
      });
      
    } catch (error) {
      console.error(chalk.red('❌ 模块生成失败:'), error.message);
    }
  }

  /**
   * 生成项目结构
   */
  async generateProjectStructure() {
    console.log(chalk.blue('🔨 正在生成项目脚手架...\n'));
    
    try {
      const structure = multiFrameworkAdapter.generateProjectStructure(this.config);
      
      // 创建项目目录结构
      await this.createDirectoryStructure(structure, this.config.outputPath);
      
      console.log(chalk.green('🎉 项目脚手架生成成功!'));
      console.log(chalk.blue(`📁 项目路径: ${path.join(this.config.outputPath, this.config.projectName)}\n`));
      
      // 显示下一步操作提示
      console.log(chalk.yellow('下一步操作:'));
      console.log(`cd ${path.join(this.config.outputPath, this.config.projectName)}`);
      console.log('npm install');
      console.log('npm run dev\n');
      
    } catch (error) {
      console.error(chalk.red('❌ 项目生成失败:'), error.message);
    }
  }

  /**
   * 创建目录结构
   */
  async createDirectoryStructure(structure, basePath) {
    for (const [name, content] of Object.entries(structure)) {
      const fullPath = path.join(basePath, name);
      
      if (typeof content === 'object' && content !== null) {
        // 创建目录
        if (!fs.existsSync(fullPath)) {
          fs.mkdirSync(fullPath, { recursive: true });
        }
        
        // 递归创建子目录和文件
        await this.createDirectoryStructure(content, fullPath);
      } else if (typeof content === 'string') {
        // 创建文件
        const dir = path.dirname(fullPath);
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }
        
        fs.writeFileSync(fullPath, content, 'utf8');
        console.log(chalk.green(`✅ 已创建: ${path.relative(basePath, fullPath)}`));
      }
    }
  }

  /**
   * 生成文件名
   */
  generateFileName(type = null) {
    const currentType = type || this.config.type;
    const { language, framework, moduleName } = this.config;
    
    // 根据语言确定文件扩展名
    const extensions = {
      javascript: '.js',
      typescript: '.ts',
      java: '.java',
      python: '.py',
      go: '.go',
      csharp: '.cs',
      php: '.php',
      ruby: '.rb',
      rust: '.rs'
    };
    
    const ext = extensions[language] || '.txt';
    
    // 根据框架和类型生成文件名
    if (framework === 'react' || framework === 'vue' || framework === 'angular') {
      return `Alyr-${moduleName}-${currentType}${ext === '.ts' ? '.tsx' : ext}`;
    } else {
      return `Alyr-${moduleName}.${currentType}${ext}`;
    }
  }

  /**
   * 显示代码预览
   */
  async showCodePreview(code) {
    const showPreview = await this.question('是否显示代码预览? (y/n): ');
    
    if (showPreview.toLowerCase() === 'y') {
      console.log(chalk.cyan('\n📋 代码预览:'));
      console.log(chalk.gray('─'.repeat(60)));
      
      // 显示前50行代码
      const lines = code.split('\n');
      const previewLines = lines.slice(0, 50);
      
      previewLines.forEach((line, index) => {
        console.log(chalk.gray(`${(index + 1).toString().padStart(3)}: `) + line);
      });
      
      if (lines.length > 50) {
        console.log(chalk.yellow(`\n... 还有 ${lines.length - 50} 行代码`));
      }
      
      console.log(chalk.gray('─'.repeat(60)));
    }
  }

  /**
   * 显示支持的技术栈
   */
  showSupportedTechStack() {
    console.log(chalk.green('\n🚀 支持的技术栈:\n'));
    
    const languages = multiFrameworkAdapter.getSupportedLanguages();
    const frameworks = multiFrameworkAdapter.getSupportedFrameworks();
    
    console.log(chalk.blue('编程语言:'));
    languages.forEach(lang => {
      console.log(chalk.cyan(`  • ${lang}`));
    });
    
    console.log(chalk.blue('\n框架支持:'));
    Object.entries(frameworks).forEach(([category, frameworkList]) => {
      console.log(chalk.yellow(`\n${category.toUpperCase()}:`));
      frameworkList.forEach(framework => {
        console.log(chalk.cyan(`  • ${framework}`));
      });
    });
    
    console.log(chalk.green('\n✨ 更多技术栈正在持续添加中...\n'));
  }

  /**
   * 询问用户输入
   */
  question(prompt) {
    return new Promise(resolve => {
      this.rl.question(chalk.white(prompt), resolve);
    });
  }
}

// 主程序入口
async function main() {
  const generator = new AlyrCodeGenerator();
  await generator.start();
}

// 如果直接运行此文件，启动CLI工具
if (require.main === module) {
  main().catch(error => {
    console.error(chalk.red('❌ 程序异常:'), error.message);
    process.exit(1);
  });
}

module.exports = AlyrCodeGenerator;